package au.com.darkside.XServer.Xext;

import java.io.IOException;

import android.util.Log;

import au.com.darkside.XServer.XServer;
import au.com.darkside.XServer.InputOutput;
import au.com.darkside.XServer.Client;
import au.com.darkside.XServer.ErrorCode;
import au.com.darkside.XServer.Util;


public class Extensions
{
	public static final byte SYNC=-127;
	public static final byte SYNC_EVENT_BASE=95;
	public static final byte SYNC_ERROR_BASE=(byte) 154;
	public static final int SYNC_INIT=0;
	public static final int SYNC_LIST=1;
	public static final int SYNC_CREATE=2;
	public static final int SYNC_DESTROY=3;
	public static final byte XGE=-128;
	public static final int XGE_INIT=0;
	public static final byte BIG_REQUESTS=-126;
	public static final byte SHAPE=-125;
	public static final byte SHAPE_EVENT_BASE=76;
	public static final int SHAPE_INIT=0;
	public static final int SHAPE_RECTANGLES=1;
	public static final int SHAPE_MASK=2;
	public static final int SHAPE_COMBINE=3;
	public static final int SHAPE_OFFSET=4;
	public static final int SHAPE_QUERY_EXTENT=5;
	public static final int SHAPE_SELECT_INPUT=6;
	public static final int SHAPE_INPUT_SELECTED=7;
	public static final int SHAPE_GET_RECTANGLES=8;
	public static final int SHAPE_BOUNDING=0;
	public static final int SHAPE_CLIP=1;
	public static final int SHAPE_INPUT=2;
	public static final int SHAPE_SET=0;
	public static final int SHAPE_UNION=1;
	public static final int SHAPE_INTERSECT=2;
	public static final int SHAPE_SUBTRACT=3;
	public static final int SHAPE_INVERT=4;
	private int xgeMajor;
	private int xgeMinor;
	private Sync _sync;

	public Extensions()
	{
		Log.e("XServExtensions","constructed!");
		_sync=new Sync();
	}

	public boolean
	processRequest (
	XServer 	xServer,
	Client		client,
	byte			opcode,
	int				arg,
	int				bytesRemaining, int _sequenceNumber
	) throws IOException
	{
		InputOutput		io = client.getInputOutput ();
		Log.i("XServExtensions","processRequest");
		Log.i("XServExtensions","Opcode:"+Integer.toString(new Integer(opcode)) +" Arg:"+Integer.toString(arg)+" seqNo:"+Integer.toString(_sequenceNumber));
		switch(opcode){
			case SYNC:
				_sync.processRequest(
				xServer, client,
				opcode, arg,
				bytesRemaining, _sequenceNumber);
				break;
			case XGE:
				switch(arg)
				{
					case XGE_INIT:
						if (bytesRemaining < 2) {
							io.readSkip (bytesRemaining);
							ErrorCode.write (client, ErrorCode.Length, opcode, 0);
						} else {
							xgeMajor=io.readByte();
							xgeMinor=io.readByte();
							bytesRemaining-=2;
							io.readSkip (bytesRemaining);
							synchronized(io)
							{
								Util.writeReplyHeader (client, arg);
								io.writeInt (0);	// Reply length.
								io.writeByte((byte) xgeMajor);
								io.writeByte((byte) xgeMinor);
								io.writePadBytes(22);
							}
							io.flush ();
							Log.i("XServExtensions","XGE - Major:"+Integer.toString(xgeMajor)+" Minor:"+Integer.toString(xgeMinor));
						}
						break;
					default:
						byte[] ba = new byte[bytesRemaining];
						io.readBytes(ba, 0, bytesRemaining);
						String str=new String(ba);
						Log.e("XServExtensions","XGE unhandled minor opcode:"+Integer.toString(arg));
						Log.e("XServExtensions","DATA:"+str);
						break;
				}
				break;
			case BIG_REQUESTS:
				synchronized(io)
				{
					Util.writeReplyHeader(client,arg);
					io.writeInt(0);
					io.writeInt(Integer.MAX_VALUE);
					io.writePadBytes(20);
				}
				io.flush();
				Log.i("XServExtensions","BIG-REQUESTS - MaxValue:"+Integer.toString(Integer.MAX_VALUE));
				break;
			case SHAPE:
				XShape.processRequest (
					xServer,	client,
				opcode,	arg,	bytesRemaining,
				_sequenceNumber	);
				break;
			default:
				byte[] ba = new byte[bytesRemaining];
				io.readBytes(ba, 0, bytesRemaining);
				String str=new String(ba);
				Log.e("XServExtensions","we can not handle this extension yet...");
				Log.e("XServExtensions","Major"+Integer.toString(opcode)+" Minor:"+Integer.toString(arg));
				Log.e("XServExtensions","DATA:"+str);
				break;
		}
		return false;
	}
}
